package org.flint92.springboot.jdbc.controller;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flint92.springboot.jdbc.domain.User;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Objects;

/**
 * @author flint92
 */
@RestController
@Slf4j
public class JdbcController {

    @Resource
    private DataSource dataSource;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/user")
    public Map<String, Object> getUser(
            @RequestParam(value = "id", defaultValue = "1") int id
    ) {

        try (
                Connection connection = dataSource.getConnection();
                PreparedStatement statement = connection.prepareStatement("select id,name,age from user where id=?")
        ) {
            // execute
            statement.setInt(1, id);
            ResultSet resultSet = statement.executeQuery();

            final Map<String, Object> result = Maps.newHashMap();
            while (resultSet.next()) {
                result.put("id", resultSet.getInt("id"));
                result.put("name", resultSet.getString("name"));
                result.put("age", resultSet.getInt("age"));
            }

            return result;
        } catch (SQLException e) {
            log.error(e.getSQLState(), e.getLocalizedMessage(), e);
        }

        return ImmutableMap.of();
    }

    @PostMapping("/user")
    public String addUser(@RequestBody User user) {
        String name = user.getName();
        if (StringUtils.isBlank(name)) {
            return "name must not empty.";
        }

        Integer age = user.getAge();
        Boolean success;
        if (Objects.isNull(age)) {
            success = jdbcTemplate.execute("insert into user(name) values(?)",
                    (PreparedStatementCallback<Boolean>) ps -> {
                        ps.setString(1, user.getName());
                        return ps.executeUpdate() > 0;
                    });

        } else {
            success = jdbcTemplate.execute("insert into user(name,age) values(?,?)",
                    (PreparedStatementCallback<Boolean>) ps -> {
                        ps.setString(1, user.getName());
                        ps.setInt(2, user.getAge());

                        return ps.executeUpdate() > 0;
                    });
        }

        return (Objects.nonNull(success) && success) ? "success" : "fail";
    }

}
